package com.kantboot.tool.edu.service.impl;

import com.alibaba.fastjson2.JSON;
import com.kantboot.global.data.change.annotaion.DataChange;
import com.kantboot.global.data.change.common.CommonDataChangeKey;
import com.kantboot.tool.edu.domain.entity.ToolEduMajor;
import com.kantboot.tool.edu.domain.entity.ToolEduMajorDegree;
import com.kantboot.tool.edu.domain.vo.ToolEduMajorHasChildren;
import com.kantboot.tool.edu.repository.ToolEduMajorDegreeRepository;
import com.kantboot.tool.edu.repository.ToolEduMajorHasChildrenRepository;
import com.kantboot.tool.edu.repository.ToolEduMajorRepository;
import com.kantboot.tool.edu.service.IToolEduMajorService;
import com.kantboot.util.common.exception.BaseException;
import com.kantboot.util.core.redis.RedisUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ToolEduMajorServiceImpl implements IToolEduMajorService {

    @Resource
    private ToolEduMajorRepository repository;

    @Resource
    private ToolEduMajorDegreeRepository degreeRepository;

    @Resource
    private ToolEduMajorHasChildrenRepository hasChildrenRepository;

    @Resource
    private RedisUtil redisUtil;


    @Override
    public ToolEduMajor getByCode(String code) {
        return repository.findByCode(code);
    }

    @Override
    public ToolEduMajorHasChildren getByCodeHasChildren(String code) {
        return hasChildrenRepository.findByCode(code);
    }

    @Override
    public List<ToolEduMajor> getAll() {
        String key = "ToolEduMajor:getAll";
        String jsonStr = redisUtil.get(key);
        if (jsonStr != null) {
            return JSON.parseArray(jsonStr, ToolEduMajor.class);
        }
        List<ToolEduMajor> all = repository.findAll();
        redisUtil.set(key, JSON.toJSONString(all));
        return all;
    }

    @Override
    public List<ToolEduMajorHasChildren> getAllHasChildren() {
        String key = "ToolEduMajor:getAllHasChildren";
        String jsonStr = redisUtil.get(key);
        if (jsonStr != null) {
            return JSON.parseArray(jsonStr, ToolEduMajorHasChildren.class);
        }
        List<ToolEduMajorHasChildren> all = hasChildrenRepository.findAll();
        redisUtil.set(key, JSON.toJSONString(all));
        return all;
    }

    /**
     * 添加学位
     */
    private void saveDegree(ToolEduMajor major) {
        List<ToolEduMajorDegree> degrees = major.getDegrees();
        degreeRepository.deleteByMajorSubjectCode(major.getCode());
        if (degrees != null) {
            for (ToolEduMajorDegree degree : degrees) {
                degree.setId(null);
                degree.setMajorSubjectCode(major.getCode());
            }
            degreeRepository.saveAll(degrees);
        }
    }

    @Override
    @DataChange(key = CommonDataChangeKey.CLIENT_INIT)
    public ToolEduMajor save(ToolEduMajor major) {
        // 删除缓存
        redisUtil.delete("ToolEduMajor:getAll");
        redisUtil.delete("ToolEduMajor:getAllHasChildren");

        // 查询是否为新增
        boolean isNew = major.getId() == null;
        if(!isNew){
            ToolEduMajor toolEduMajor = repository.findById(major.getId()).orElse(null);
            if(toolEduMajor == null){
                isNew = true;
            }
        }
        // 如果是新增
        if (isNew) {
            // 查询是否存在相同编码
            ToolEduMajor byCode = repository.findByCode(major.getCode());
            // 如果存在相同编码
            if (byCode != null) {
                // 抛出异常,编码重复
                throw BaseException.of("codeRepeat", "编码重复");
            }
            saveDegree(major);
            return repository.save(major);
        }

        // 如果编码为空
        if (major.getCode() == null) {
            // 编码不可为空
            throw BaseException.of("codeNotNull", "编码不可为空");
        }

        // 如果编码发生变化
        ToolEduMajor byCode = repository.findByCode(major.getCode());
        if (byCode != null && !byCode.getId().equals(major.getId())) {
            throw BaseException.of("codeRepeat", "编码重复");
        }


        saveDegree(major);
        return repository.save(major);
    }

    @Override
    @DataChange(key = CommonDataChangeKey.CLIENT_INIT)
    public void remove(ToolEduMajor major) {
        // 删除缓存
        redisUtil.delete("ToolEduMajor:getAll");
        redisUtil.delete("ToolEduMajor:getAllHasChildren");
        repository.findById(major.getId()).orElseThrow(() -> BaseException.of("majorNotFound", "专业不存在"));
        repository.deleteById(major.getId());
    }
}
